import io from 'socket.io-client';
import { observable, computed, action } from 'mobx';
import _ from 'lodash';
import {
	sleep,
	promiseTimeout,
	createSocketIOSendWaitor,
} from './common/tools';

import { net as netAPI } from './protocolConst.json';

export var socket;
export var sendAction;
export var sendActionAndWait;
export var connect = function() {
	let url = process.env.REACT_APP_API_SERVER || 'APISERVERNOTSET';
	//如果只指定了端口号，那么认为在同一服务器上
	if (/^:\d+/.test(url)) {
		url = location.hostname + url;
	}
	socket = io(url);
	let sio = createSocketIOSendWaitor(socket);
	sendAction = sio.sendAction;
	sendActionAndWait = sio.sendActionAndWait;

	socket.on('connect', () => {
		(async () => {
			store.netState = 'connect';
		})();
	});
	socket.on('disconnect', () => {
		socket.id = null;
		store.netState = 'disconnect';
	});

	socket.on('action', action => {
		console.log('recv action', action.type, action);
		if (action.type == netAPI.onScan) {
			let { id, qrCode, userdata, scanCount } = action.payload;
			store.setQRCode(userdata, id, qrCode, scanCount);
		} else if (action.type == netAPI.onLogin) {
			let { id, name, avatar } = action.payload;
			store.setLoginIn(id, name, avatar);
			// store.setQRCode(userdata, id, qrCode, scanCount);
		} else if (action.type == netAPI.onLogout) {
			let { id } = action.payload;
			store.setLoginOut(id);
		}
	});
};

export var doWhenConnect = f => {
	if (socket.id) {
		f();
	} else {
		socket.once('connect', f);
	}
};

class AppStore {
	@observable
	netState = 'disconnect';

	@observable
	accounts = [];

	@observable
	agents = [];

	constructor() {
		this.createTime = new Date().toString();
		this.tmUpdate = setInterval(this.onUpdate.bind(this), 1000);
		if (!this.load()) {
			this.addAccount();
		}
	}

	async requestAllAgents() {
		let res = await sendActionAndWait(netAPI.getAllAgents, {}, 10 * 1000);
		this.agents = res.payload;
	}

	addAccount(id?: string, options?: Object) {
		this.accounts.push({
			id,
			options,
			isLogin: false,
			enable: true,
		});
	}

	getAccount(index) {
		return this.accounts[index];
	}

	setQRCode(index, id, qrCode, scanCount) {
		let account = this.accounts[index];
		if (!account) return;
		account.id = id;
		account.qrCode = qrCode;
		account.scanCount = scanCount;
		this.save();
	}

	clearAccount(index) {
		let account = this.accounts[index];
		account.id = undefined;
		account.err = undefined;
		account.isLogining = false;
		this.save();
	}

	closeAccount(index) {
		this.accounts[index] = undefined;
		_.remove(this.accounts, (v, k) => k == index);
		this.save();
	}

	sendControlCommand(index, cmd) {
		console.log('sendControlCommand', index, cmd);
		let account = this.accounts[index];
		if (!account) return;
		sendActionAndWait(netAPI.sendControlCommand, {
			id: account.id,
			cmd,
		});
	}

	sendMessage(index, targetId, text) {
		console.log('sendmessage', index, targetId, text);
		let account = this.accounts[index];
		if (!account) return;
		sendActionAndWait(netAPI.sendMessage, {
			id: account.id,
			contactId: targetId,
			text,
		});
	}

	setLoginOut(id) {
		let account = this.accounts.filter(v => v.id == id)[0];
		if (!account) return;
		account.name = undefined;
		account.qrCode = undefined;
	}
	setLoginIn(id, name, avatar) {
		let account = this.accounts.filter(v => v.id == id)[0];
		if (!account) return;
		account.name = name;
		account.qrCode = undefined;
		account.avatar = avatar;
		this.refreshRooms(account);
	}

	async refreshRooms(account) {
		let res = await sendActionAndWait(
			netAPI.getRooms,
			{ id: account.id },
			10 * 1000
		);
		account.rooms = res.payload;
	}

	load() {
		let data = localStorage.getItem('account');
		if (!data) return false;
		console.log('load', data);
		this.accounts = JSON.parse(data);
		return true;
	}

	save() {
		let data = this.accounts.map((v, k) => {
			return { id: v.id, options: v.options };
		});
		localStorage.setItem('account', JSON.stringify(data));
		console.log('save', data);
	}

	onUpdate() {
		this.accounts.map(async (v, k) => {
			// if (!v.enable) return;
			if (!v.isLogin) {
				if (!v.isLogining) {
					v.isLogining = true;

					let res = sendAction(netAPI.requestLogin, {
						id: v.id,
						options: v.options,
						userdata: k,
					});
				}
			}
		});
	}
}
export var store = new AppStore();
console.log('create store', store.createTime);
